package genome;

public class grammar {
	
	private static int point = 0;
	private static int loop = 0;
	
	private static int mx_depth;
	
	private static GGT g;
	
	public static void setGGT(GGT pG){
		g = pG;
		point = 0;
		loop = 0;
		mx_depth = pG.maxDepth;
	}
	
	public static double eval(){
		return eval(0);
	}
	
	public static double eval(int depth){
		checkPoint();
		int dec = g.genome[point];
		
		int nArg = 2;
		
		//System.out.println("Decision for EVAL at point "+point+" is "+dec%nArg);
		
		if(depth==mx_depth){
			dec = 1; //return terminal
		}
		
		switch(dec%nArg){
			case 0:
				point++;
				return fn(depth+1);
			
			case 1:
				point++;
				return T();
		}
		return 0.0;
	}
	
	public static double fn(int depth){
	
		int nArg = 2;
		
		double x;
		double y;
		
		x = eval(depth);
		y = eval(depth);
		
		checkPoint();
		int dec = g.genome[point];
		//System.out.println("Decision for function at point "+point+" is "+dec%nArg);
		
		switch(dec%nArg){
			
			case 0:
				point++;
				return x+y;
				
			case 1:
				point++;
				return x-y;
		}
		return 0.0;
	}

	public static double T(){
		int nArg = 2;
		checkPoint();
		int dec = g.genome[point];
		//System.out.println("Decision for terminal at point "+point+" is "+dec%nArg);
		
		switch(dec%nArg){
			case 0:
				point++;
				return g.input[0];
			
			case 1:
				point++;
				return g.input[1];
		}
		return 0.0;
	}

	public static String evalS(){
		return evalS(0);
	}
	
	public static String evalS(int depth){
		checkPoint();
		int dec = g.genome[point];
		
		if(depth==mx_depth){
			dec = 1;
		}
		
		int nArg = 2;
		
		switch(dec%nArg){
			case 0:
				point++;
				return fnS(depth+1);
			
			case 1:
				point++;
				return TS();
		}
		return "";
	}
	
	public static String fnS(int depth){
	
		int nArg = 2;
		
		String x;
		String y;
		
		x = evalS(depth);
		y = evalS(depth);
		
		checkPoint();
		switch(g.genome[point]%nArg){
			case 0:
				point++;
				return "["+x+"+"+y+"]";
			
			case 1:
				point++;
				return "["+x+"-"+y+"]";
		}
		return "0.0";
	}
	
	public static String TS(){
		int nArg = 2;
		checkPoint();
		switch(g.genome[point]%nArg){
			case 0:
				point++;
				return "v";
			
			case 1:
				point++;
				return "i";
		}
		return "0.0";
	}
	
	public static void checkPoint(){
		if(!(point<g.size)){
			point = 0; //loop
			loop++;
		}
	}
}
